//! 格式化器集成测试
//!
//! 测试 Formatter trait 和 TextFormatter 的功能。

use log4r::formatter::{Formatter, TextFormatter};
use log4r::{Level, LogEvent};

// IT-2.5-001: 测试 TextFormatter 实现 Formatter trait (AC: 2.5.1)
#[test]
fn test_text_formatter_implements_formatter_trait() {
    // GIVEN: TextFormatter 作为 trait object
    let formatter: Box<dyn Formatter> = Box::new(TextFormatter::new());
    let event = LogEvent::new(Level::Info, "test_app", "测试消息");

    // WHEN: 调用 format 方法
    let output = formatter.format(&event);

    // THEN: 应返回非空字符串
    assert!(!output.is_empty());
    assert!(output.contains("test_app"));
    assert!(output.contains("测试消息"));
}

// IT-2.5-002: 测试输出格式正确 (AC: 2.5.2)
#[test]
fn test_text_formatter_output_format() {
    // GIVEN: TextFormatter 和 LogEvent
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Info, "my_app::module", "Hello, world!");

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 输出格式应为 {time} [{level}] {target}: {message}
    // 验证各部分存在
    assert!(output.contains("[INFO ]"), "应包含级别标记");
    assert!(output.contains("my_app::module:"), "应包含 target 和冒号");
    assert!(output.contains("Hello, world!"), "应包含消息");

    // 验证格式顺序：时间在最前，然后是级别，然后是 target，最后是消息
    let level_pos = output.find("[INFO ]").unwrap_or(usize::MAX);
    let target_pos = output.find("my_app::module:").unwrap_or(usize::MAX);
    let message_pos = output.find("Hello, world!").unwrap_or(usize::MAX);

    assert!(level_pos < target_pos, "级别应在 target 之前");
    assert!(target_pos < message_pos, "target 应在消息之前");
}

// IT-2.5-003: 测试时间格式正确（毫秒精度）(AC: 2.5.3)
#[test]
fn test_text_formatter_time_format_millisecond_precision() {
    // GIVEN: TextFormatter 和 LogEvent
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Info, "test", "message");

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 时间格式应为 YYYY-MM-DD HH:MM:SS.mmm（23 字符）
    // 格式示例：2025-12-01 10:30:45.123
    let time_part = &output[..23];

    // 验证年份（4 位数字）
    let year: i32 = time_part[..4].parse().unwrap_or(0);
    assert!(
        (2020..=2100).contains(&year),
        "年份应在合理范围内: {}",
        year
    );

    // 验证分隔符
    assert_eq!(&time_part[4..5], "-", "年月分隔符应为 '-'");
    assert_eq!(&time_part[7..8], "-", "月日分隔符应为 '-'");
    assert_eq!(&time_part[10..11], " ", "日期时间分隔符应为空格");
    assert_eq!(&time_part[13..14], ":", "时分分隔符应为 ':'");
    assert_eq!(&time_part[16..17], ":", "分秒分隔符应为 ':'");
    assert_eq!(&time_part[19..20], ".", "秒毫秒分隔符应为 '.'");

    // 验证毫秒部分（3 位数字）
    let millis: i32 = time_part[20..23].parse().unwrap_or(-1);
    assert!(
        (0..=999).contains(&millis),
        "毫秒应在 0-999 范围内: {}",
        millis
    );
}

// IT-2.5-004: 测试级别固定宽度 5 字符 (AC: 2.5.4)
#[test]
fn test_text_formatter_level_fixed_width_5_chars() {
    // GIVEN: TextFormatter
    let formatter = TextFormatter::new();

    // WHEN/THEN: 所有级别应格式化为固定宽度 5 字符
    let levels = [
        (Level::Trace, "TRACE"),
        (Level::Debug, "DEBUG"),
        (Level::Info, "INFO "),
        (Level::Warn, "WARN "),
        (Level::Error, "ERROR"),
        (Level::Fatal, "FATAL"),
    ];

    for (level, expected_padded) in levels {
        let event = LogEvent::new(level, "test", "message");
        let output = formatter.format(&event);

        // 提取 [XXXXX] 部分
        let bracket_start = output.find('[').expect("应包含 '['");
        let bracket_end = output.find(']').expect("应包含 ']'");
        let level_str = &output[bracket_start + 1..bracket_end];

        assert_eq!(
            level_str.len(),
            5,
            "级别 {:?} 应为 5 字符宽度，实际: '{}' (长度 {})",
            level,
            level_str,
            level_str.len()
        );

        assert_eq!(
            level_str, expected_padded,
            "级别 {:?} 应为 '{}'，实际: '{}'",
            level, expected_padded, level_str
        );
    }
}

// IT-2.5-005: 测试 Send + Sync 编译时验证 (AC: 2.5.5)
#[test]
fn test_text_formatter_send_sync() {
    // GIVEN/WHEN: 编译时断言函数
    fn assert_send<T: Send>() {}
    fn assert_sync<T: Sync>() {}
    fn assert_send_sync<T: Send + Sync>() {}

    // THEN: TextFormatter 应实现 Send + Sync（编译通过即验证成功）
    assert_send::<TextFormatter>();
    assert_sync::<TextFormatter>();
    assert_send_sync::<TextFormatter>();
}

// IT-2.5-006: 测试各级别格式化输出
#[test]
fn test_all_levels_format_correctly() {
    // GIVEN: TextFormatter
    let formatter = TextFormatter::new();

    // WHEN/THEN: 所有级别应正确格式化
    let test_cases = [
        (Level::Trace, "[TRACE]", "跟踪信息"),
        (Level::Debug, "[DEBUG]", "调试信息"),
        (Level::Info, "[INFO ]", "一般信息"),
        (Level::Warn, "[WARN ]", "警告信息"),
        (Level::Error, "[ERROR]", "错误信息"),
        (Level::Fatal, "[FATAL]", "致命错误"),
    ];

    for (level, expected_level_bracket, message) in test_cases {
        let event = LogEvent::new(level, "my_app", message);
        let output = formatter.format(&event);

        assert!(
            output.contains(expected_level_bracket),
            "级别 {:?} 应包含 '{}'，实际输出: {}",
            level,
            expected_level_bracket,
            output
        );

        assert!(
            output.contains(message),
            "应包含消息 '{}'，实际输出: {}",
            message,
            output
        );

        assert!(
            output.contains("my_app:"),
            "应包含 target 'my_app:'，实际输出: {}",
            output
        );
    }
}

// IT-2.5-007: 测试 Formatter trait 可以作为 trait object 使用
#[test]
fn test_formatter_as_trait_object() {
    // GIVEN: 多个格式化器作为 trait object
    let formatters: Vec<Box<dyn Formatter>> = vec![
        Box::new(TextFormatter::new()),
        Box::new(TextFormatter::new()), // 两个实例验证 trait object
    ];

    let event = LogEvent::new(Level::Info, "test", "message");

    // WHEN/THEN: 所有格式化器应正常工作
    for formatter in formatters {
        let output = formatter.format(&event);
        assert!(output.contains("[INFO ]"));
        assert!(output.contains("test:"));
        assert!(output.contains("message"));
    }
}

// IT-2.5-008: 测试中文消息格式化
#[test]
fn test_chinese_message_formatting() {
    // GIVEN: 包含中文的日志事件
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Info, "我的应用::模块", "服务启动成功，欢迎使用！");

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 中文应正确显示
    assert!(output.contains("我的应用::模块:"), "应包含中文 target");
    assert!(
        output.contains("服务启动成功，欢迎使用！"),
        "应包含中文消息"
    );
}

// IT-2.5-009: 测试空消息格式化
#[test]
fn test_empty_message_formatting() {
    // GIVEN: 空消息的日志事件
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Warn, "test", "");

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 应正常格式化（消息为空）
    assert!(output.contains("[WARN ]"));
    assert!(output.contains("test:"));
    assert!(output.ends_with(": ") || output.ends_with(":"));
}

// IT-2.5-010: 测试长消息格式化
#[test]
fn test_long_message_formatting() {
    // GIVEN: 长消息的日志事件
    let formatter = TextFormatter::new();
    let long_message = "A".repeat(1000);
    let event = LogEvent::new(Level::Debug, "test", long_message.clone());

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 长消息应完整保留
    assert!(output.contains(&long_message));
}

// ============================================================================
// 新增边界条件测试
// ============================================================================

// IT-2.5-011: 测试特殊字符消息格式化
#[test]
fn test_special_characters_formatting() {
    // GIVEN: 包含特殊字符的日志事件
    let formatter = TextFormatter::new();
    let special_chars = "特殊字符: \t\n\r {} [] () <> \"'\\";
    let event = LogEvent::new(Level::Info, "test", special_chars);

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 特殊字符应保留
    assert!(output.contains(special_chars), "特殊字符应保留在输出中");
}

// IT-2.5-012: 测试多线程并发格式化
#[test]
fn test_concurrent_formatting() {
    use std::sync::Arc;
    use std::thread;

    // GIVEN: 共享的 TextFormatter
    let formatter = Arc::new(TextFormatter::new());
    let mut handles = vec![];

    // WHEN: 多线程并发格式化
    for i in 0..10 {
        let formatter_clone = Arc::clone(&formatter);
        let handle = thread::spawn(move || {
            let event = LogEvent::new(Level::Info, "thread_test", format!("线程 {} 消息", i));
            formatter_clone.format(&event)
        });
        handles.push(handle);
    }

    // THEN: 所有线程应成功完成
    for handle in handles {
        let result = handle.join().expect("线程应成功完成");
        assert!(result.contains("[INFO ]"), "输出应包含级别");
        assert!(result.contains("thread_test:"), "输出应包含 target");
    }
}

// IT-2.5-013: 测试 FATAL 级别格式化
#[test]
fn test_fatal_level_formatting() {
    // GIVEN: FATAL 级别事件
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Fatal, "critical_module", "系统崩溃");

    // WHEN: 格式化事件
    let output = formatter.format(&event);

    // THEN: 应正确格式化 FATAL 级别
    assert!(output.contains("[FATAL]"), "应包含 FATAL 级别");
    assert!(output.contains("critical_module:"), "应包含 target");
    assert!(output.contains("系统崩溃"), "应包含消息");
}

// IT-2.5-014: 测试 Default trait 实现
#[test]
fn test_formatter_default_trait() {
    // GIVEN: 验证 TextFormatter 实现 Default trait
    fn assert_default<T: Default>() {}
    assert_default::<TextFormatter>();

    // WHEN: 使用 new() 创建（等效于 default()）
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Debug, "test", "debug message");
    let output = formatter.format(&event);

    // THEN: 应正常工作
    assert!(output.contains("[DEBUG]"), "格式化器应正常工作");
}

// IT-2.5-015: 测试 Clone trait 实现
#[test]
fn test_formatter_clone_trait() {
    // GIVEN: TextFormatter 实例
    let formatter = TextFormatter::new();
    let event = LogEvent::new(Level::Warn, "test", "warning");

    // WHEN: 克隆格式化器
    let cloned = formatter.clone();

    // THEN: 克隆应产生相同输出
    let output1 = formatter.format(&event);
    let output2 = cloned.format(&event);
    assert_eq!(output1, output2, "克隆的格式化器应产生相同输出");
}
